package com.ray.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.xmlbeans.impl.jam.mutable.MPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.ray.bean.DatatablesViewPageBean;
import com.ray.bean.FeedOrderDetailBean;
import com.ray.bean.OrderInfoDetailBean;
import com.ray.bean.OrderReceiveViewBean;
import com.ray.bean.ProcessBean;
import com.ray.bean.ReportBean;
import com.ray.bean.WarehouseInOutDetailBean;
import com.ray.bean.WorkshopMaterialStockCountBean;
import com.ray.exception.ServiceException;
import com.ray.mapper.BasicDataMapper;
import com.ray.mapper.IssueNoteMapper;
import com.ray.mapper.OrderMapper;
import com.ray.mapper.WarehouseMapper;
import com.ray.pojo.MyUser;
import com.ray.util.RequestUtil;
import com.ray.util.ReturnStringUtil;
import com.ray.util.StringUtil;

import net.sf.json.JSONArray;

/**
 * 发料单Service
* <p>Title: IssueNoteService</p>  
* <p>Description: </p>  
* @author 李斌  
* @date 2018年9月4日
 */
@Service
public class IssueNoteService {
	
	@Autowired
	OrderMapper orderMapper;
	@Autowired
	IssueNoteMapper issueNoteMapper;
	@Autowired
	BasicDataMapper basicDataMapper;
	@Autowired
	WarehouseMapper warehouseMapper;
	@Autowired
	WorkshopService workShopService;
	@Autowired
	BasicDataService basicDataService;
	@Autowired 
	OrderService orderService;
	@Autowired
	CompanyMaterialService companyMaterialService;
	
	/**
	 * @isUrl true 
	 * 查询可生成发料单的数据
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<FeedOrderDetailBean> getFeedMaterialData(Map<String, String> map) {
		List<FeedOrderDetailBean> feedOrderDetailBeans = issueNoteMapper.getFeedMaterialData(map);
		int count = issueNoteMapper.getFeedMaterialDataCount(map);
		DatatablesViewPageBean<FeedOrderDetailBean> dtcpb = new DatatablesViewPageBean<FeedOrderDetailBean>();
		dtcpb.setReturnData(feedOrderDetailBeans);
		dtcpb.setiTotalDisplayRecords(count); 
		dtcpb.setiTotalRecords(count);
		return dtcpb;
	}
	
	/**
	 * 获取订单领取数量明细
	 * nate 2019-01-07
	 * orderIdList  订单编号集合
	 * orderId 单个订单编号
	 * materialType 物料类型
	 * rowIndex 行号
	 * materialCode 物料代码
	 * @param paramMap
	 * @return
	 */
	public  List<OrderReceiveViewBean> getOrderReceiveCount(Map paramMap) {
		List<OrderReceiveViewBean> returnList=issueNoteMapper.getOrderReceiveCount(paramMap);
		returnList=null==returnList?new ArrayList<OrderReceiveViewBean>():returnList;
		return returnList;
	}

	/**
	 * 获取物料未审核数量
	 * materialCode 物料代码
	 * materialCodeList 批量
	 * loginCompany 登录公司
	 * @param map
	 * @return
	 */
	public  List<OrderReceiveViewBean> getMaterialNotApprovalCount(Map map){
		List<OrderReceiveViewBean> returnList=issueNoteMapper.getMaterialNotApprovalCount(map);
		returnList=null==returnList?new ArrayList<OrderReceiveViewBean>():returnList;
		return returnList;
	}
	

	/**
	 * @isUrl true
	 * 获取已生成的发料单
	* @date 2018年9月6日 上午10:19:57 
	* @author 李斌
	* @return Object 
	* @throws
	 */ 
	public DatatablesViewPageBean<WarehouseInOutDetailBean> getIssueData(Map<String, Object> map) {
		List<WarehouseInOutDetailBean> warehouseInOutDetailBeans = warehouseMapper.getWarehouseInOutDetailData(map);
		List<String> putOutUserList = workShopService.getPutOutApprovalUserName(map);
		int canApproval = putOutUserList.indexOf(map.get("loginUserName"));
		for(WarehouseInOutDetailBean warehouseInOutDetailBean:warehouseInOutDetailBeans) {
			if(warehouseInOutDetailBean.getStatus()==0) {
				if(warehouseInOutDetailBean.getSource() !=null 
					&& warehouseInOutDetailBean.getSource().intValue()==2) {
					if(canApproval>-1) {
						warehouseInOutDetailBean.setIsApperval(1);
					}else {
						warehouseInOutDetailBean.setIsApperval(0);
					}
					warehouseInOutDetailBean.setAuditableUser(putOutUserList);
				}else {
					List<String> pickingPeople = new ArrayList<String>();
					pickingPeople.add(warehouseInOutDetailBean.getPickingPeople());
					warehouseInOutDetailBean.setAuditableUser(pickingPeople);
				}
			}
		}
		int count =warehouseMapper.getWarehouseInOutDetailCount(map);
		DatatablesViewPageBean<WarehouseInOutDetailBean> datatablesViewPageBean = new DatatablesViewPageBean<WarehouseInOutDetailBean>();
		datatablesViewPageBean.setiTotalDisplayRecords(count);
		datatablesViewPageBean.setiTotalRecords(count);
		datatablesViewPageBean.setReturnData(warehouseInOutDetailBeans);
		return datatablesViewPageBean;
	}
	
	/**
	 * @isUrl true 
	 * 获取那些没有生产的订单明细信息
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<OrderInfoDetailBean> getOrderInfoDetailByNotProduct(Map<String, Object> map) {
		DatatablesViewPageBean<OrderInfoDetailBean> datatablesViewPageBean = new DatatablesViewPageBean<OrderInfoDetailBean>();
		List<OrderInfoDetailBean> orderInfoDetailList =  issueNoteMapper.getOrderInfoDetailByNotProductData(map);
		int count = issueNoteMapper.getOrderInfoDetailByNotProductCount(map);
		datatablesViewPageBean.setiTotalDisplayRecords(count);
		datatablesViewPageBean.setiTotalRecords(count);
		datatablesViewPageBean.setReturnData(orderInfoDetailList);
		return datatablesViewPageBean;
	}



	/**
	 * @isUrl true 
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<WarehouseInOutDetailBean> getIssueDataByIds(Map<String, Object> map) {
		Assert.notNull(map.get("ids"), "参数不全异常 ids为空");
		String ids = map.get("ids").toString();
		map.put("ids",ids.split(","));
		map.put("sourceType", 1);
		return this.getIssueData(map);
	}
	
	
    /**
     * @isUrl true
     * 获取车间仓库数量
     * @param map
     * @return
     */
	public DatatablesViewPageBean<FeedOrderDetailBean> getWorkShopWarehouseMaterialCount(Map<String, Object> map) {
		DatatablesViewPageBean<FeedOrderDetailBean> datatablesViewPageBean = new DatatablesViewPageBean<FeedOrderDetailBean>();
		List<FeedOrderDetailBean> orderInfoDetailList =  issueNoteMapper.getWorkShopWarehouseMaterialDate(map);
		int count = issueNoteMapper.getWorkShopWarehouseMaterialCount(map);
		datatablesViewPageBean.setiTotalDisplayRecords(count);
		datatablesViewPageBean.setiTotalRecords(count);
		datatablesViewPageBean.setReturnData(orderInfoDetailList);
		return datatablesViewPageBean;
	}
	
	/**
	 * 获取无订单发料投料单
	 * @param map
	 * @return
	 */
	public List<FeedOrderDetailBean> getWorkShopWarehouseMaterialDate(Map map){
		return issueNoteMapper.getWorkShopWarehouseMaterialDate(map);
	}
	
	/**
	 * @isUrl true 
	 * jsonArray 
	 * orderId 订单编号
	 * workShopName 车间id
	 * materialCode 物料代码
	 * rowIndex 行号
	 * color 色号
	 * machining 物料类型
	 * qualified 合格数
	 * materialCount 物料数量
	 * materialUnit 物料单位
	 * id 投料单id
	 * 手动发料
	 * @param map
	 * @return
	 * @throws CloneNotSupportedException 
	 * @throws ServiceException 
	 */
	public String manualIssue(Map map) throws ServiceException, CloneNotSupportedException {
		StringUtil.checkIsTrue(map, "jsonArray", "未获取到参数");
		String jsonStr=map.get("jsonArray").toString();
		JSONArray jsonArray=JSONArray.fromObject(jsonStr);
		List<ReportBean> list=(List<ReportBean>) JSONArray.toCollection(jsonArray, ReportBean.class);
		Map<String,List<ReportBean>> reportMap=list.stream().collect(Collectors.groupingBy(ReportBean::getOrderId));
		HttpServletRequest request=(HttpServletRequest) map.get("request");
		MyUser myUser=RequestUtil.getLoginUser(request);
		//校验领料数是否超过实际领料数
		this.checkFeedOrderReceiveCount(list);
		//校验库存数是否足够
		this.checkWorkShopMaterialCount(list,myUser);
		for(String key:reportMap.keySet()) {
			List<ReportBean> oneOrderList=reportMap.get(key);
			oneOrderList.forEach(report->{
				report.setAuditor(null);
				report.setAuditorTime(null);
				report.setStatus(0);
			});
			this.insertReport(oneOrderList,myUser);
		}
		return ReturnStringUtil.SAVE_SUCCESS;
	}
	
	/**
	 * 校验投料单领料数
	 * @param list
	 */
	public  void checkFeedOrderReceiveCount(List<ReportBean> list) {
		List<FeedOrderDetailBean> feedList=new ArrayList<FeedOrderDetailBean>();
		list.forEach(report->{
			FeedOrderDetailBean feedOrderDetailBean= orderService.getFeedOrderDetailOneById(report.getId());
			Assert.notNull(feedOrderDetailBean,"投料单不存在或已退回");
			BigDecimal useFactoryCount = new BigDecimal(feedOrderDetailBean.getUseFactoryCount().toString());
			BigDecimal receiveCount = new BigDecimal(feedOrderDetailBean.getReceiveCount().toString());
			BigDecimal materialCount = new BigDecimal(report.getMaterialCount()+"");
			Assert.isTrue(useFactoryCount.subtract(receiveCount).subtract(materialCount).doubleValue()>=0,report.getOrderId()+":"+report.getMachining()+"最多还可以发料" +(useFactoryCount.subtract(receiveCount).doubleValue()));
		    if(feedOrderDetailBean.getReceiveCount()+report.getMaterialCount()>= feedOrderDetailBean.getUseFactoryCount()) {
		    	feedOrderDetailBean.setIsReceiveFinish(1);
		    }
		    feedOrderDetailBean.setReceiveCount(receiveCount.add(materialCount).doubleValue());
		    feedList.add(feedOrderDetailBean);
		});
		Map map = new HashMap();
		map.put("feedList", feedList);
		companyMaterialService.updateFeedOrderDetailReceive(map); 
	}

	/**
	 * 校验车间物料库存
	 * @param list
	 * @param myUser 
	 */
	public  void checkWorkShopMaterialCount(List<ReportBean> list, MyUser myUser) {
		Map<String,List<ReportBean>> workShopMaterialListMap=list.stream().collect(Collectors.groupingBy(report->report.getMaterialCode()+report.getWorkShopName()));
	    Map map=new HashMap();
	    Set<String> materialCodeSet=list.stream().map(ReportBean::getMaterialCode).collect(Collectors.toSet());
	    map.put(map, map);
	    map.put("loginCompany", myUser.getCompany());
	    List<WorkshopMaterialStockCountBean> stoctList=this.getWorkShopMaterialCount(map);
	    for(String key :workShopMaterialListMap.keySet()) {
	    	List<ReportBean> reportList=workShopMaterialListMap.get(key);
	    	//需要使用的数量
	        double usedCount=reportList.stream().mapToDouble(ReportBean::getMaterialCount).sum();
	        //库存数量
	        double stoctCount=stoctList.stream().filter(tt->key.equals(tt.getMaterialCode()+tt.getWorkShopId())).mapToDouble(WorkshopMaterialStockCountBean::getActualCount).sum();
	        Assert.isTrue(stoctCount>=usedCount,reportList.get(0).getMachining()+"库存不足，合计最多可出库"+stoctCount);
	    }
	}

	/**
	 * 审核状态与审核人在
	 * 单个订单报工
	 * @param oneOrderList
	 * @param myUser
	 * @throws CloneNotSupportedException 
	 * @throws ServiceException 
	 */
	public  void insertReport(List<ReportBean> oneOrderList,MyUser myUser) throws ServiceException, CloneNotSupportedException {
		ProcessBean processBean =basicDataService.getProcessByWorkShopId(oneOrderList.get(0).getWorkShopName());
		Assert.notNull(processBean,"该车间没有交接入库工序");
		oneOrderList.forEach(xx->{
			xx.setCompany(myUser.getCompany());
			xx.setProcedurText("交接入库");
			xx.setProcedur(processBean.getId()+"");
			xx.setTouchPeople(myUser.getUserId());//报工人暂定为制单人
			xx.setReport(myUser.getUserId());
			xx.setType(1);//是交接入库
			xx.setOtherType(-2);//无订单发料交接
			xx.setMachingType(0);//单物料
		});
		JSONArray jsonArray=JSONArray.fromObject(oneOrderList);
		//在报工方法中不需要在检验是否自动交接入库
		myUser.setIsUpdate(ReturnStringUtil.REPORT_NOT_CHECKING_AUTO_IN);
		workShopService.insertReport(jsonArray.toString(), "", myUser);
		
	}
	
	/**
	 * @isUrl true
	 * 获取车间库存
	 * @param map
	 * @return
	 */
	public List<WorkshopMaterialStockCountBean> getWorkShopMaterialCount(Map map){
		return issueNoteMapper.getWorkShopMaterialCount(map);
	}

	/**
	 * @isUrl true 
	 * 获取车间库存  分页
	 */
	public DatatablesViewPageBean<WorkshopMaterialStockCountBean> getWorkShopMaterialCountPage(Map map){
		DatatablesViewPageBean<WorkshopMaterialStockCountBean> datatablesViewPageBean=new DatatablesViewPageBean<WorkshopMaterialStockCountBean>();
		List<WorkshopMaterialStockCountBean> list=this.getWorkShopMaterialCount(map);
		int count=issueNoteMapper.getWorkShopMaterialCountPageCount(map);
		datatablesViewPageBean.setReturnData(list);
		datatablesViewPageBean.setiTotalRecords(count);
		datatablesViewPageBean.setiTotalDisplayRecords(count);
		return datatablesViewPageBean;
	}
}
